package bibbletex.models;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.sql.ResultSet;
import java.sql.SQLException;
import bibbletex.helpers.SQLHelper;

/**
 * Collaboration class is the model for a collaboration.
 * 
 * It contains the basic attributes plus a list of references.
 * 
 * @author Diego Barrios Romero
 * 
 */
public class Collaboration {

	/**
	 * Unique identifier. This will also work as the primary key in the
	 * database.
	 */
	UUID id;
	String title, description, creator_name, email;

	List<Reference> references;

	/**
	 * When a collaboration is created, a new random UUID is associated to be
	 * able to identify it and later on, associate it with the references.
	 */
	public Collaboration(RequestCollaboration rc) {
		id = UUID.randomUUID();
		references = new ArrayList<Reference>();

		setTitle(rc.getTitle());
		setDescription(rc.getDescription());
		setCreator_name(rc.getCreator_name());
		setEmail(rc.getEmail());

		Collaboration.save(this);
	}

	public Collaboration(UUID id) {
		this.id = id;
		references = new ArrayList<Reference>();
	}

	public UUID getId() {
		return id;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = new String(title);
		Collaboration.save(this);
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = new String(description);
		Collaboration.save(this);
	}

	public String getCreator_name() {
		return creator_name;
	}

	public void setCreator_name(String creator_name) {
		this.creator_name = new String(creator_name);
		Collaboration.save(this);
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = new String(email);
		Collaboration.save(this);
	}

	public List<Reference> getReferences() {
		return references;
	}

	public boolean addReference(Reference r) {
		if (r == null)
			System.err.println("r is null!");
		references.add(r);
		boolean success = false;

		// The Collaboration must be already saved
		// we save the reference
		success = Reference.save(r);

		// and the association
		if (success)
			success = SQLHelper
					.execSQL("insert into collaboration_reference values('"
							+ id + "', '" + r.getId() + "')");

		return success;
	}

	public boolean deleteReference(Reference r) {
		boolean success = false;
		references.remove(r);
		success = Reference.delete(r);

		// and the association
		if (success)
			success = SQLHelper
					.execSQL("delete from collaboration_reference where reference_id='"
							+ r.getId() + "'");

		return success;
	}

	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj instanceof Collaboration) {
			Collaboration other = (Collaboration) obj;
			// By definition, the UUID are uniques so we only need to
			// compare the ID
			return (id.equals(other.id));
		} else {
			return false;
		}
	}

	/* CLASS METHODS */
	/**
	 * This method saves, or updates if it's already present, a given Collaboration in the database
	 * 
	 * WARNING: This method does not save the references.
	 * 
	 * @param c Collaboration to save / update
	 * @return Whether the operation was successful
	 */
	private static boolean save(Collaboration c) {
		ResultSet rs = null;
		boolean success = false;

		// if the collaboration exists, update, if not, insert
		rs = SQLHelper.execQuerySQL("select * from collaboration where id = '"
				+ c.getId() + "'");
		try {
			if (rs.next()) {
				// Update
				success = SQLHelper.execSQL("update collaboration set id = '"
						+ c.getId() + "', title = '" + c.getTitle()
						+ "', description = '" + c.getDescription()
						+ "', creator_name = '" + c.getCreator_name()
						+ "', email = '" + c.getEmail() + "' where id = '"
						+ c.getId() + "'");
			} else {
				// Insert
				success = SQLHelper
						.execSQL("insert into collaboration values('"
								+ c.getId() + "', '" + c.getTitle() + "', '"
								+ c.getDescription() + "', '"
								+ c.getCreator_name() + "', '" + c.getEmail()
								+ "')");
			}
		} catch (SQLException e) {
			System.err.println("Collaboration.save: " + e);
		}

		return success;
	}

	/**
	 * Deletes a collaboration from the database and all the references
	 * associated
	 * 
	 * @param c
	 *            Collaboration
	 * @return Whether it was successful
	 */
	public static boolean delete(Collaboration c) {
		boolean success = false;
		ResultSet rs = null;

		// get all associations
		rs = SQLHelper
				.execQuerySQL("select reference_id from collaboration_reference where collaboration_id='"
						+ c.getId() + "'");

		try {
			// delete all associated references
			while (rs.next() && success)
				success = SQLHelper.execSQL("delete from reference where id='"
						+ rs.getString("reference_id") + "'");

			// delete all associations
			if (rs.next() && success)
				success = SQLHelper
						.execSQL("delete from collaboration_reference where collaboration_id='"
								+ c.getId() + "'");

		} catch (SQLException e) {
			System.err.println("Collaboration.delete: "+e);
		}

		// Now that all the dependences have been deleted, delete the
		// collaboration
		if (success)
			success = SQLHelper.execSQL("delete from collaboration where id='"
					+ c.getId() + "'");

		return success;
	}

	/**
	 * Load the Collaboration with the given ID from the database 
	 * @param id UUID from the Collaboration
	 * @return Loaded Collaboration
	 */
	public static Collaboration load(String id) {
		Collaboration c = null;
		ResultSet rs = null;

		try {
			rs = SQLHelper
					.execQuerySQL("select * from collaboration where id='" + id
							+ "'");

			if (rs.next()) {
				c = new Collaboration(UUID.fromString(rs.getString("id")));
				c.setTitle(rs.getString("title"));
				c.setDescription(rs.getString("description"));
				c.setCreator_name(rs.getString("creator_name"));
				c.setEmail(rs.getString("email"));

				// Load the references
				ResultSet col_refs = null;

				col_refs = SQLHelper
						.execQuerySQL("select * from collaboration_reference where collaboration_id='"
								+ c.getId() + "'");

				while (col_refs.next()) {
					Reference r = Reference.load(col_refs
							.getString("reference_id"));
					if (r != null)
						c.addReference(r);
				}
			}
		} catch (SQLException e) {
			System.err.println("Collaboration.load: " + e);
		}

		return c;
	}
}
